<?php

namespace MoChat\App\Sales\Command;

use Hyperf\Command\Command as HyperfCommand;
use Hyperf\DbConnection\Db;
use Hyperf\Redis\Redis;
use Hyperf\Utils\ApplicationContext;
use Psr\Container\ContainerInterface;
use Symfony\Component\Console\Input\InputArgument;
use TheSeer\Tokenizer\Exception;
use Hyperf\Command\Annotation\Command;

/**
 * @Command
 */
class SalesTaskCommand extends HyperfCommand
{
    /**
     * @var ContainerInterface
     */
    protected $container;

    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;

        parent::__construct('salesTask');
    }

    public function configure()
    {
        parent::configure();
        $this->addOption('clear', 'C', InputArgument::OPTIONAL, '清除redis', 0);
        $this->setDescription('销售任务同步');
    }

    public function handle()
    {
        $container = ApplicationContext::getContainer();
        $redis = $container->get(Redis::class);
        $clear = $this->input->getOption('clear');
        if ($clear) {
            $redis->del('SalesTaskCommand_key');
        }
        $bool = $redis->get('SalesTaskCommand_key');
        if ($bool) {
            $this->line('上一个销售任务同步脚本程序正在执行中', 'info');
        } else {
            $redis->set('SalesTaskCommand_key', true);
            $maxId = $redis->get('SalesTaskCommand_key_max_id');
            $maxId = $maxId ?: 0;
            Db::beginTransaction();
            try {
                $tasks = Db::table('sales_task_employee')
                    ->where('status', 0)
                    ->select([
                        'work_employee_id',
                        'start_time',
                        'end_time',
                        'sales_task',
                        'id',
                    ])
                    ->where('id', '>', $maxId)
                    ->limit(10)
                    ->orderBy('id', 'asc')->get();
                if (empty($tasks)) {
                    $redis->set('SalesTaskCommand_key_max_id', 0);
                    throw new Exception('没有需要处理的数据');
                }
                $tasks = $tasks->toArray();
                $startKey = array_unique(array_column($tasks, 'start_time'));
                $endKey = array_unique(array_column($tasks, 'end_time'));
                sort($startKey, SORT_STRING);
                rsort($endKey, SORT_STRING);
                $startTime = reset($startKey);
                $endTime = reset($endKey);
                $workEmployeeId = array_unique(array_column($tasks, 'work_employee_id'));
                $contacts = Db::table('work_contact_employee')->whereIn('employee_id', $workEmployeeId)->select([
                    'contact_id',
                    'employee_id',
                ])->get();
                $contacts = empty($contacts) ? [] : $contacts->toArray();
                if (empty($contacts)) {
                    $redis->set('SalesTaskCommand_key_max_id', 0);
                    throw new Exception('没有需要处理的数据');
                }
                foreach ($tasks as &$task) {
                    $task->contact_ids = [];
                    foreach ($contacts as $contact) {
                        if ($contact->employee_id == $task->work_employee_id) {
                            $task->contact_ids[] = $contact->contact_id;
                        }
                    }
                }
                unset($task);
                $contactIds = array_unique(array_column($contacts, 'contact_id'));
                $clientContactPivots = Db::table('client_contact_pivot')
                    ->whereIn('contact_id', $contactIds)
                    ->select([
                        'client_id',
                        'contact_id'
                    ])->get();
                if (empty($clientContactPivots)) {
                    $redis->set('SalesTaskCommand_key_max_id', 0);
                    throw new Exception('没有客户');
                }
                $clientContactPivots = $clientContactPivots->toArray();
                foreach ($tasks as &$task) {
                    $task->client_ids = [];
                    foreach ($clientContactPivots as $clientContactPivot) {
                        if (in_array($clientContactPivot->contact_id, $task->contact_ids)) {
                            $task->client_ids[] = $clientContactPivot->client_id;
                        }
                    }
                }
                unset($task);
                $clientIds = array_unique(array_column($clientContactPivots, 'client_id'));
                $orders = Db::connection('b2b')
                    ->table('user_order')
                    ->join('order_status as status', 'status.ID', '=', 'user_order.ID')
                    ->whereIn('user_order.USER_ID', $clientIds)
                    ->where('status.PAYMENT', 1)
                    ->where('user_order.CREATE_TIME', '>=', $startTime)
                    ->where('user_order.CREATE_TIME', '<', $endTime)
                    ->select([
                        'user_order.TOTAL_AMOUNT',
                        'user_order.USER_ID',
                        'user_order.CREATE_TIME'
                    ])
                    ->get();
                $orders = empty($orders) ? [] : $orders->toArray();
                foreach ($tasks as &$task) {
                    $task->completed = 0;
                    if (!empty($orders)) {
                        $taskStartTime = strtotime($task->start_time);
                        $taskEndTime = strtotime($task->end_time);
                        foreach ($orders as $order) {
                            $createTime = strtotime($order->CREATE_TIME);
                            if (in_array($order->USER_ID, $task->client_ids) && $createTime >= $taskStartTime && $createTime < $taskEndTime) {
                                $task->completed += $order->TOTAL_AMOUNT;
                            }
                        }
                    }
                }
                unset($task);
                foreach ($tasks as $task) {
                    $progressRate = $task->sales_task ? bcmul(bcdiv((string)$task->completed, (string)$task->sales_task, 5), 100, 2) . '%' : '100%';
                    $taskEndTime = strtotime($task->end_time);
                    $status = 0;
                    if ($taskEndTime <= time()) {
                        $status = 1;
                    }
                    Db::table('sales_task_employee')
                        ->where('id', $task->id)
                        ->update([
                            'completed' => $task->completed,
                            'progress' => $progressRate,
                            'status' => $status,
                            'updated_at' => date('Y-m-d H:i:s')
                        ]);
                }
                $maxId = end($tasks)->id;
                $redis->set('SalesTaskCommand_key_max_id', $maxId);
                Db::commit();
            } catch (\Throwable $throwable) {
                Db::rollBack();
            }
            $redis->del('SalesTaskCommand_key');
            $this->line('销售任务同步处理完成', 'info');
        }
    }
}